package com.liangwj.springbootquickstart.jdk8.lambda;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
 * <b>Description:</b> Java8 Lambda 学习 <br/>
 * @author Lingwenjun
 * @date 2019/1/9-11:18
 * @version 1.0
 */
public class LambdaDemo {

    private final static String[] ARR = {"lianggzone", "spring", "summer"};

    /**
     * 注意点
     * lambda表达式执行返回类型，会根据上下文推到出来，我们不需要设置它的返回类型。
     * lambda表达式中，只有某些分支中返回值，这样是错误的。
     */

    /**
     * compare
     */
    //在java8 之前,借助匿名内部类实现
    public static List<String> compareTest1() {
        List<String> wordList = Arrays.asList(ARR);
        wordList.sort(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return Integer.compare(o1.length(), o2.length());
            }
        });
        return wordList;
    }

    //java8.函数式接口--Lambda实现
    public static List<String> compareTest2() {
        List<String> wordList = Arrays.asList(ARR);
        wordList.sort( (String o1, String o2) -> {
            return Integer.compare(o1.length(), o2.length());
        } );
        return wordList;
    }

    //java8.函数式接口--Lambda实现--如果一个lambda表达式的参数类型是可以被推导的，那么就可以省略它们的类型。
    public static List<String> compareTest3() {
        List<String> wordList = Arrays.asList(ARR);
        wordList.sort( (o1, o2) -> {
            return Integer.compare(o1.length(), o2.length());
        } );
        return wordList;
    }

    //java8.函数式接口--Lambda实现--如果一个Lambda的表达式代码块只是return后面跟一个表达式,那么还可以进一步简化
    public static List<String> compareTest4() {
        List<String> wordList = Arrays.asList(ARR);
        wordList.sort( (s1, s2) -> Integer.compare(s1.length(), s2.length()));
        return wordList;
    }

    //java8.函数式接口--Lambda实现--IDEA recommend
    public static List<String> compareTest5() {
        List<String> wordList = Arrays.asList(ARR);
        wordList.sort(Comparator.comparingInt(String::length));//lambda表达式还可以进一步简化为方法引用。：：操作符将方法名和对象或类的名字分隔开来。
        return wordList;
    }

    //java8.函数式接口--Lambda实现--如果某个方法只含有一个参数，并且该参数的类型可以被推导出来，你甚至可以省略小括号。
    public static List<String> compareTest6() {
        List<String> wordList = Arrays.asList(ARR);
        wordList.forEach( word -> System.out.println("word = " + word));
        return wordList;
    }

    /**
     * runnable
     */
    //当我们需要在另一个独立线程中执行一些逻辑时,通常会将代码放在一个实现Runnable接口的类的run方法中
    public static void runnableTest1() {
        Executors.newSingleThreadExecutor().execute(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    System.out.println("i = " + i);
                }
            }
        });
    }

    //如果lambda表达式没有参数, 你仍可以提供一对小括号,如同不含参数的方法
    public static void runnableTest2() {
        Executors.newSingleThreadExecutor().execute(() -> {
            for (int i = 0; i < 10; i++) {
                System.out.println("i = " + i);
            }
        });
        Executors.newSingleThreadExecutor().execute(System.out::println);
    }


}
